#include "KAcceptorAction.h"
#include "KSocket.h"

KAcceptorAction::KAcceptorAction(LONG max, LONG extra)
    : m_clients(0), m_extra(extra), m_total(0), m_max(max)
{
    assert(m_extra >= 0);
}

void KAcceptorAction::decreaseClients()
{
    LONG current = InterlockedDecrement(&m_clients);
    assert(current >= 0);
    onClientsChanged(current);
}

void KAcceptorAction::onFault(KDef::SockError type, DWORD error, LONG extra)
{
    KDebugMsg("Server fault: type = %d, error = %d, extra = %d", type, error, extra);
}

void KAcceptorAction::onAccepted(KSocket *client)
{
    LONG current = InterlockedIncrement(&m_clients);
    InterlockedIncrement(&m_total);
    if (m_max < 0 || current <= m_max) {
        if (onNewClient(client)) {
            onClientsChanged(current);
            return;
        }
    } else {
        KDebugMsg("Warning: clients too many, connection refused");
    }
    InterlockedDecrement(&m_clients);
    client->shutdown();
    client->close();
}

void KAcceptorAction::onFatalError(KDef::SockError type, DWORD error)
{
    onFault(type, error, InterlockedDecrement(&m_extra));
}